package com.zgc.view.controller;

import com.fx.spring.annotation.ControllerFX;
import com.fx.spring.controller.AbstractController;
import com.jfoenix.controls.JFXAlert;
import com.jfoenix.controls.JFXTextField;
import com.zgc.cache.ZkServiceCache;
import com.zgc.zkinfo.ZkConnectionInfo;
import com.zgc.zkinfo.ZkService;
import com.zgc.zkinfo.ZkServiceFactory;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Spinner;
import javafx.scene.control.SpinnerValueFactory.IntegerSpinnerValueFactory;
import javafx.scene.image.Image;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import org.apache.curator.framework.imps.CuratorFrameworkState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import java.net.URL;
import java.util.ResourceBundle;

@ControllerFX(fxmlURL = "/view/fxml/NewConnection.fxml")
public class NewConnectionCtrl extends AbstractController<VBox> {

    @FXML
    private JFXTextField nameField;
    @FXML
    private JFXTextField addressField;
    @FXML
    private VBox connectionDialogRoot;

    @FXML
    private Spinner<Integer> portSpinner;
    @FXML
    private Spinner<Integer> connectTimeoutSpinner;
    @FXML
    private Spinner<Integer> sessionTimeSpinner;
    @FXML
    private Spinner<Integer> connectWaitSpinner;

    @Autowired
    private ProgressAlertCtrl alertProgressAlertCtrl;

    private JFXAlert<String> alert;
    private ZkConnectionInfo zkConnectionInfo;

    /** 初始化 */
    @FXML
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        logger.debug("[{}]初始化完成", location);
        alert = initAlert();
        this.portSpinner.setValueFactory(setSpinnerValueFactory(1, 65535, 2181));
        this.connectTimeoutSpinner.setValueFactory(setSpinnerValueFactory(1000, Integer.MAX_VALUE, 30000));
        this.sessionTimeSpinner.setValueFactory(setSpinnerValueFactory(1000, Integer.MAX_VALUE, 30000));
        this.connectWaitSpinner.setValueFactory(setSpinnerValueFactory(0, Integer.MAX_VALUE, 10000));
    }

    public void showNewConnectionAlert() {
        showConnectionAlert();
        alert.setTitle("新建连接");
    }

    public void showEditConnectionAlert(ZkConnectionInfo zkConnectionInfo) {
        this.zkConnectionInfo = zkConnectionInfo;
        showConnectionAlert();
        alert.setTitle("编辑连接");
        nameField.setText(zkConnectionInfo.getName());
        String host = zkConnectionInfo.getHost();
        if (!StringUtils.isEmpty(host)) {
            String[] split = host.split(":");
            addressField.setText(split[0]);
            portSpinner.setValueFactory(setSpinnerValueFactory(1, 65535, Integer.parseInt(split[1])));
        }
        connectTimeoutSpinner.setValueFactory(setSpinnerValueFactory(1000, Integer.MAX_VALUE, zkConnectionInfo.getConnectionTimeoutMs()));
        sessionTimeSpinner.setValueFactory(setSpinnerValueFactory(1000, Integer.MAX_VALUE, zkConnectionInfo.getSessionTimeoutMs()));
        connectWaitSpinner.setValueFactory(setSpinnerValueFactory(0, Integer.MAX_VALUE, zkConnectionInfo.getConnectionWaitTimeout()));

    }

    /** 测试连接 */
    @FXML
    private void testConnect(ActionEvent actionEvent) {
        getZkConnectionInfo();
        ZkServiceFactory.getZkService(zkConnectionInfo.getId())
                .startAndAlert(zkConnectionInfo, alertProgressAlertCtrl);

    }


    /** 测试 */
    @FXML
    private void test(ActionEvent actionEvent) {
        ZkService zkService = ZkServiceCache.getService(zkConnectionInfo.getId());
        if (zkConnectionInfo != null && zkService != null) {
            CuratorFrameworkState state = zkService.getValue().getState();
            logger.info("zookeeper：[{}]连接状态 {}", addressField.getText(), state);
        } else {
            logger.info("zookeeper：[{}]连接状态为空", addressField.getText());
        }
    }


    /** 确定 */
    @FXML
    private void ok(ActionEvent actionEvent) {
        getZkConnectionInfo();
    }

    /** 应用 */
    @FXML
    private void apply(ActionEvent actionEvent) {
        getZkConnectionInfo();
        alert.close();
    }

    /** 设置转换工厂，用来解决开启可编辑状态后，输入的非数字问题 */
    private IntegerSpinnerValueFactory setSpinnerValueFactory(int min, int max, int defaultValue) {
        // 转换器 只匹配数字
        IntegerSpinnerValueFactory valueFactory = new IntegerSpinnerValueFactory(min, max);
        valueFactory.setValue(defaultValue);
        valueFactory.setConverter(new StringConverter<>() {
            @Override
            public String toString(Integer object) {
                return object.toString();
            }

            @Override
            public Integer fromString(String string) {
                if (string.matches("^[1-9]\\d*$")) {
                    return Integer.parseInt(string);
                }
                return defaultValue;
            }
        });
        return valueFactory;
    }

    private void getZkConnectionInfo() {
        zkConnectionInfo = new ZkConnectionInfo()
                .setName(nameField.getText())
                .setHost(addressField.getText() + ":" + portSpinner.getValue())
                .setConnectionTimeoutMs(connectTimeoutSpinner.getValue())
                .setSessionTimeoutMs(sessionTimeSpinner.getValue())
                .setConnectionWaitTimeout(connectWaitSpinner.getValue())
                .commit();
    }

    private void showConnectionAlert() {
        // 先加载在设置
        VBox load = this.load();
        alert.setContent(load);
        alert.show();
    }

    private JFXAlert<String> initAlert() {
        JFXAlert<String> alert = new JFXAlert<>();
        alert.setSize(600, 350);
        Stage window = (Stage) alert.getDialogPane().getScene().getWindow();
        window.getIcons().add(new Image("/view/images/icon.png"));
        return alert;
    }
}
